package com.tqz.rc.server.cluster;

import com.tqz.rc.common.util.EnvUtil;
import com.tqz.rc.common.util.StringUtils;

import java.util.*;

/**
 * <p>
 *
 * @author tianqingzhao
 * @since 2021/9/24 10:32
 */
public class MemberUtils {

    public static final String SERVER_PORT_PROPERTY = "server.port";

    public static final int DEFAULT_SERVER_PORT = 8848;

    public static final int DEFAULT_RAFT_OFFSET_PORT = 1000;

    public static final String RAFT_PORT = "raftPort";

    public static final String IPV6_START_MARK = "[";

    public static final String IPV6_END_MARK = "]";

    public static Collection<Member> readServerConf(Collection<String> members) {
        Set<Member> nodes = new HashSet<>();

        for (String member : members) {
            Member target = singleParse(member);
            nodes.add(target);
        }

        return nodes;
    }

    public static Member singleParse(String member) {
        // Nacos default port is 8848
        int defaultPort = EnvUtil.getProperty(SERVER_PORT_PROPERTY, Integer.class, DEFAULT_SERVER_PORT);
        // Set the default Raft port information for securit

        String address = member;
        int port = defaultPort;
        String[] info = splitIPPortStr(address);
        if (info.length > 1) {
            address = info[0];
            port = Integer.parseInt(info[1]);
        }

        Member target = Member.builder().ip(address).port(port).state(NodeState.UP).build();

        Map<String, Object> extendInfo = new HashMap<>(4);
        // The Raft Port information needs to be set by default
        extendInfo.put(RAFT_PORT, String.valueOf(calculateRaftPort(target)));
        target.setExtendInfo(extendInfo);
        return target;
    }

    public static int calculateRaftPort(Member member) {
        return member.getPort() - DEFAULT_RAFT_OFFSET_PORT;
    }

    /**
     * 根据地址分隔ip和端口号，比如：http://192.168.1.1:8080  分割成 http://192.168.1.1和8080
     *
     * @param str 地址
     * @return
     */
    public static String[] splitIPPortStr(String str) {
        if (StringUtils.isBlank(str)) {
            throw new IllegalArgumentException("ip and port string cannot be empty!");
        }
        String[] serverAddrArr;
        if (str.startsWith(IPV6_START_MARK) && StringUtils.containsIgnoreCase(str, IPV6_END_MARK)) {
            if (str.endsWith(IPV6_END_MARK)) {
                serverAddrArr = new String[1];
                serverAddrArr[0] = str;
            } else {
                serverAddrArr = new String[2];
                serverAddrArr[0] = str.substring(0, (str.indexOf(IPV6_END_MARK) + 1));
                serverAddrArr[1] = str.substring((str.indexOf(IPV6_END_MARK) + 2));
            }
        } else {
            serverAddrArr = str.split(":");
        }
        return serverAddrArr;
    }

    /**
     * 从服务端的集群里面获取地址
     *
     * @param members members
     * @return address list
     */
    public static List<String> simpleMembers(Collection<Member> members) {
        return members.stream().map(Member::getAddress).sorted()
                .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
    }
}
